﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DbSharp.ConsoleRunner.Parser
{
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
    public abstract class ArgumentAttribute : Attribute
    {
        private Argument argument;

        /// <summary>
        /// The underlying Argument type
        /// </summary>
        public Argument Argument
        {
            get { return argument; }
        }

        /// <summary>
        /// Creates new instance of ArgumentAttribute.
        /// </summary>
        /// <param name="underlyingArgumentType">Type of the underlying argument.</param>
        /// <param name="constructorParams">Parameters of the constructor of underlying argument</param>
        protected ArgumentAttribute(Type underlyingArgumentType, params object[] constructorParams)
        {
            if (!underlyingArgumentType.IsSubclassOf(typeof(Argument)))
            {
                throw new InvalidOperationException("Parameter underlyingArgumentType must be a subclass of Argument.");
            }
            //create argument object of proper type using reflection
            argument = (Argument)Activator.CreateInstance(underlyingArgumentType, constructorParams);
        }

        #region delegated argument members

        /// <summary>
        /// Description of the argument 
        /// </summary>
        public string Description
        {
            get { return argument.Description; }
            set { argument.Description = value; }
        }

        /// <summary>
        /// Long, full description of the argument. 
        /// </summary>
        public string FullDescription
        {
            get { return argument.FullDescription; }
            set { argument.FullDescription = value; }
        }

        /// <summary>
        /// Long name of the argument. Can apear on the command line in --<i>longName</i> format.
        /// Must be one word. 
        /// </summary>
        /// <exception cref="CommandLineFormatException">Name is invalid</exception>
        public string LongName
        {
            get { return argument.LongName; }
            set { argument.LongName = value; }
        }

        /// <summary>
        /// Mark argument optional. Arguments with Optional = false can be checked in <see cref="CommandLineParser.ParseCommandLine(string[])"/> method.
        /// <see cref="CommandLineParser.CheckMandatoryArguments"/>
        /// <remarks>Default is true</remarks>
        /// </summary>
        public bool Optional
        {
            get { return argument.Optional; }
            set { argument.Optional = value; }
        }

        /// <summary>
        /// Allows argument to appear multiple times on the command line. Default is false.
        /// </summary>
        public bool AllowMultiple
        {
            get { return Argument.AllowMultiple; }
            set { Argument.AllowMultiple = value; }
        }

        /// <summary>
        /// Long name of the argument. Can apear on the command line in -<i>shortName</i> format.
        /// </summary>
        /// <exception cref="CommandLineFormatException">Name is invalid</exception>
        public char ShortName
        {
            get { return argument.ShortName; }
            set { argument.ShortName = value; }
        }

        #endregion

    }
}
